package com.yixuan.mt.core.handler;

import com.yixuan.mt.core.exception.HttpMethodNotSupportException;
import com.yixuan.mt.core.pojo.ChannelAttributes;
import com.yixuan.mt.core.response.FixedResponse;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * 在处理完请求行和请求头就会调用该 handler
 */
@Component
@ChannelHandler.Sharable
public class RequestHandler extends ChannelInboundHandlerAdapter {

    @Autowired
    private DoRequest doRequest;

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws IOException {
        // 传递过来的是请求行和请求头的数据
        if (msg instanceof HttpRequest) {
            AbstractController controller = null;
            HttpRequest httpRequest = (HttpRequest) msg;
            ctx.channel().attr(ChannelAttributes.httpRequestAttributeKey).set(httpRequest);

            try {
                controller = doRequest.handle((HttpRequest) msg);
            } catch (HttpMethodNotSupportException ex) {
                FixedResponse.sendMethodNotAllowedResponse(ctx);
                ctx.close();
                return;
            }
            if (!HttpUtil.isContentLengthSet(httpRequest)) {
                controller.handle(ctx, httpRequest, null);
            } else {
                // 这里简单的借助 headers 去设置响应的阶段（后面改进）
                httpRequest.headers().set("responseState", 0);
                ctx.channel().attr(ChannelAttributes.controllerAttributeKey).set(controller);
            }
        }
        // 传递过来的是请求体的数据
        else {
            AbstractController controller = ctx.channel().attr(ChannelAttributes.controllerAttributeKey).get();
            HttpRequest httpRequest = ctx.channel().attr(ChannelAttributes.httpRequestAttributeKey).get();
            controller.handle(ctx, httpRequest, (HttpContent) msg);
        }
    }
}
